package ${packageName};
                    
import mobile.game.core.CallPoint;
import mobile.game.core.Port;
<#if hasDefault>
import mobile.game.core.config.JowDistr;
import mobile.game.core.support.log.LogCore;
</#if>
import mobile.game.core.support.Param;
import mobile.game.core.support.Utils;
import mobile.game.core.support.function.*;
import mobile.game.core.gen.proxy.RPCProxyBase;
<#if importPackages??>
<#list importPackages as package>
import ${package};
</#list>
</#if>
import mobile.game.core.gen.JowGenFile;

${mainAnnotation}
@JowGenFile
public final class ${className}Proxy extends RPCProxyBase {
	public final class EnumCall{
		<#assign i = 0>
		<#list methods as method>
		<#assign i = i + 1>
		public static final int ${method.enumCall} = ${i};
		</#list>
	}
	<#if hasDefault>
	private static final String SERV_ID = "${servId}";
	</#if>
	
	private CallPoint remote;
	private Port localPort;
	private String callerInfo;
	
	/**
	 * 私有构造函数
	 * 防止实例被私自创建 必须通过newInstance函数
	 */
	private ${className}Proxy() {}

	<#if hasDefault>
	/**
	 * 获取实例
	 * 大多数情况下可用此函数获取
	 * @param localPort
	 * @return
	 */
	public static ${className}Proxy newInstance() {
		String portId = JowDistr.getPortId(SERV_ID);
		if(portId == null) {
			LogCore.remote.error("通过servId未能找到上级Port: servId={}", SERV_ID);
			return null;
		}
	
		String nodeId = JowDistr.getNodeId(portId);
		if(nodeId == null) {
			LogCore.remote.error("通过portId未能找到上级Node: portId={}", portId);
			return null;
		}
	
		return createInstance(nodeId, portId, SERV_ID);
	}
	</#if>
	
	<#if !hasDefault>
	/**
	 * 获取实例
	 * @return
	 */
	public static ${className}Proxy newInstance(CallPoint targetPoint) {
		return createInstance(targetPoint.nodeId, targetPoint.portId, targetPoint.servId);
	}
	
	/**
	 * 获取实例
	 * @return
	 */
	public static ${className}Proxy newInstance(String node, String port, Object id) {
		return createInstance(node, port, id);
	}
	</#if>
	
	/**
	 * 创建实例
	 * @param localPort
	 * @param node
	 * @param port
	 * @param id
	 * @return
	 */
	private static ${className}Proxy createInstance(String node, String port, Object id) {
		${className}Proxy inst = new ${className}Proxy();
		inst.localPort = Port.getCurrent();
		inst.remote = new CallPoint(node, port, id);
		
		return inst;
	}
	
	/**
	 * 监听返回值
	 * @param obj
	 * @param methodName
	 * @param context
	 */
	public void listenResult(JowFunction2<Param, Param> method, Object...context) {
		listenResult(method, new Param(context));
	}
	
	/**
	 * 监听返回值
	 * @param obj
	 * @param methodName
	 * @param context
	 */
	public void listenResult(JowFunction2<Param, Param> method, Param context) {
		context.put("_callerInfo", callerInfo);
		localPort.listenResult(method, context);
	}
	
	
	public void listenResult(JowFunction3<Boolean, Param, Param> method, Object...context) {
		listenResult(method, new Param(context));
	}
	
	public void listenResult(JowFunction3<Boolean, Param, Param> method, Param context) {
		context.put("_callerInfo", callerInfo);
		localPort.listenResult(method, context);
	}
	
	
	/**
	 * 等待返回值
	 */
	public Param waitForResult() {
		return localPort.waitForResult();
	}
	<#list methods as method>
	
	public void ${method.name}(${method.params}) {
		callerInfo = Utils.getCallerInfo();
		localPort.call(remote, EnumCall.${method.enumCall}, new Object[]{ ${method.paramsCall} });
	}
	</#list>
}